#include "mousecontroller.h"
#include "wsyperspectivecamera.h"

#include "wsymath/wsymath.h"

#include <QDebug>

/** 鼠标按下的事件 */
void MouseController::mousePressEvent(QMouseEvent *event) {
    qDebug() << "OpenGL canvas pressed. (X:"<< event->x() <<" Y:"<< event->y() << ")";
    initX = event->x(); initY = event->y();
    mousePressed = true;
    WSYPerspectiveCamera *camera = (WSYPerspectiveCamera *)scene->getCamera();
    Vertex3D *position = camera->getPosition();
    lookAt = camera->getLookAt();
    up = camera->getUpright()->normalize();
    Vector3D *lookAtCameraDirection = Math3D::direction(lookAt, position);
    lookAtCameraDistance = lookAtCameraDirection->length();
    Vector3D *dirY = Math3D::crossVectors(up, lookAtCameraDirection);
    Vector3D *dirX = Math3D::crossVectors(dirY, up);

    Vector3D *eDirY = Math3D::crossVectors(lookAtCameraDirection, dirX)->normalize();
    Vector3D *eDirY2 = dirY->normalize();

    QList<Vector3D *> *vector3DAll = new QList<Vector3D *>();
    vector3DAll->push_back(eDirY);
    vector3DAll->push_back(eDirY2);
    Vector3D *added = Math3D::addVectors(vector3DAll);

    dirX0 = dirX->normalize();
    dirY0 = dirY->normalize();
    dirZ0 = up->normalize();

    initialAngle = Math3D::angleOfTwoVectorsInRad(lookAtCameraDirection, dirX);


    if (round(added->length()) == 0) {
        initialAngle = -initialAngle;
    }

    qDebug() << "The GCL News";

}
/** 鼠标移动的事件 */
void MouseController::mouseMoveEvent(QMouseEvent *event) {
    //qDebug() << "When the mouse moves over the local canvas. (X:"<< event->x() <<" Y:"<< event->y() << ")";

    int XGap = event->x() - initX, YGap = initY - event->y();
    XGap = -XGap; YGap = -YGap;

    /**
     * @brief xAngle X轴旋转角度
     */
    double xAngleInDegree = ((double)XGap) / (double)(widget->height()) * 180;
    /**
     * @brief yAngle y轴旋转角度
     */
    double yAngleInDegree = ((double)YGap) / (double)(widget->height()) * 180;

    //qDebug() << xAngleInDegree << " " << yAngleInDegree;

    //qDebug() << "mouse status: " << mousePressed;

    double xAngleInRadian = WSYMath::DegreeToRadian(xAngleInDegree),
           yAngleInRadian = initialAngle + WSYMath::DegreeToRadian(yAngleInDegree);

    double baseLength = lookAtCameraDistance * cos(yAngleInRadian);
    double baseHeight = lookAtCameraDistance * sin(yAngleInRadian);

    Vector3D *dirX = dirX0->multiply(baseLength * cos(xAngleInRadian)),
             *dirY = dirY0->multiply(baseLength * sin(xAngleInRadian)),
             *dirZ = dirZ0->multiply(baseHeight);


    WSYPerspectiveCamera *camera = (WSYPerspectiveCamera *)scene->getCamera();
    Vertex3D *newCameraPosition = lookAt->addVectors(dirX)->addVectors(dirY)->addVectors(dirZ);
    camera->setPosition(newCameraPosition->getX(), newCameraPosition->getY(), newCameraPosition->getZ());
    double uDX = up->getDeltaX(), uDY = up->getDeltaY(), uDZ = up->getDeltaZ();

    double times = abs(yAngleInRadian) / (M_PI / 2);
    double times_2 = WSYMath::remainder(times, 2);

    //qDebug() << times;
    //qDebug() << times_2;

    if (abs(yAngleInRadian) > M_PI / 2) {
        camera->setUpright(-uDX, -uDY, -uDZ);
    } else {
        camera->setUpright(uDX, uDY, uDZ);
    }

    delete newCameraPosition;
    delete dirX; delete dirY; delete dirZ;
}
/** 鼠标松开的事件 */
void MouseController::mouseReleaseEvent(QMouseEvent *event) {
    qDebug() << "The mouse was released. (X:"<< event->x() <<" Y:"<< event->y() << ")";
    mousePressed = false;

    delete dirX0; delete dirY0; delete dirZ0;
}
